#include "ir_receiver.h"
#include "config.h"
#include "debug.h"
#include "led.h"
#include "menu.h"

// 定义红外遥控器按键码（根据用户提供的按键码定义）
const unsigned long CH = 0xff629d;               // LED 亮度开关
const unsigned long CH_DOWN = 0xffa25d;         // LED 亮度减小
const unsigned long CH_UP = 0xffe21d;           // LED 亮度增加
const unsigned long PLAY_UP = 0xff22dd;         // 七彩方向+
const unsigned long PLAY_DOWN = 0xff02fd;       // 七彩方向-
const unsigned long PLAY_AUTO = 0xffc23d;       // 七彩自动模式
const unsigned long AUDIO_DOWN = 0xffe01f;      // 音频降低音量
const unsigned long AUDIO_UP = 0xffa857;        // 音频增加音量
const unsigned long AUDIO_EQ = 0xff906f;        // 自适应音量

const unsigned long N0 = 0xff6897;   
const unsigned long N100 = 0xff9867; 
const unsigned long N200 = 0xffb04f;

// 新增七彩模式按键
const unsigned long N1 = 0xff30cf;              // 七彩模式1
const unsigned long N2 = 0xff18e7;              // 七彩模式2
const unsigned long N3 = 0xff7a85;              // 七彩模式3
const unsigned long N4 = 0xff10ef;              // 七彩模式4
const unsigned long N5 = 0xff38c7;              // 七彩模式5
const unsigned long N6 = 0xff5aa5;              // 七彩模式6

// 新增峰值点控制按键
const unsigned long N7 = 0xff42bd;              // 峰值点0个
const unsigned long N8 = 0xff4ab5;              // 峰值点1个
const unsigned long N9 = 0xff52ad;              // 峰值点2个

// NEC协议时序定义 (微秒)
#define NEC_HEADER_HIGH 9000
#define NEC_HEADER_LOW 4500
#define NEC_BIT_HIGH 560
#define NEC_BIT_ONE_LOW 1690
#define NEC_BIT_ZERO_LOW 560

// 静态变量初始化
volatile bool IRReceiver::irReceived = false;
volatile unsigned long IRReceiver::irCode = 0;
volatile unsigned long IRReceiver::lastTime = 0;
volatile int IRReceiver::bitCount = 0;
volatile unsigned long IRReceiver::data = 0;

// 实例化全局红外接收器对象
IRReceiver g_irReceiver(IR_RECEIVER_PIN);

// 构造函数
IRReceiver::IRReceiver(uint8_t pin) : pin_(pin), initialized_(false) {
}

// GPIO中断处理函数
void IRAM_ATTR IRReceiver::irInterrupt() {
    unsigned long currentTime = micros();
    unsigned long pulseWidth = currentTime - lastTime;
    lastTime = currentTime;
    
    // 简单的NEC协议解码
    if (decodeNEC(pulseWidth)) {
        irReceived = true;
    }
}

// 简化的NEC协议解码
bool IRReceiver::decodeNEC(unsigned long pulseWidth) {
    static bool headerReceived = false;
    static bool expectingHigh = true;
    
    if (!headerReceived) {
        // 等待引导码
        if (expectingHigh && isValidPulse(pulseWidth, NEC_HEADER_HIGH, 1000)) {
            expectingHigh = false;
            return false;
        } else if (!expectingHigh && isValidPulse(pulseWidth, NEC_HEADER_LOW, 1000)) {
            headerReceived = true;
            expectingHigh = true;
            bitCount = 0;
            data = 0;
            return false;
        } else {
            expectingHigh = true;
            return false;
        }
    } else {
        // 解码数据位
        if (expectingHigh) {
            if (isValidPulse(pulseWidth, NEC_BIT_HIGH, 300)) {
                expectingHigh = false;
                return false;
            } else {
                // 重置状态
                headerReceived = false;
                expectingHigh = true;
                return false;
            }
        } else {
            // 低电平脉冲，判断是0还是1
            if (isValidPulse(pulseWidth, NEC_BIT_ONE_LOW, 400)) {
                data |= (1UL << (31 - bitCount));
            } else if (!isValidPulse(pulseWidth, NEC_BIT_ZERO_LOW, 300)) {
                // 无效脉冲，重置
                headerReceived = false;
                expectingHigh = true;
                return false;
            }
            
            bitCount++;
            expectingHigh = true;
            
            if (bitCount >= 32) {
                // 接收完成
                irCode = data;
                headerReceived = false;
                expectingHigh = true;
                return true;
            }
        }
    }
    
    return false;
}

// 检查脉冲时序是否有效
bool IRReceiver::isValidPulse(unsigned long duration, unsigned long expected, unsigned long tolerance) {
    return (duration >= (expected - tolerance)) && (duration <= (expected + tolerance));
}

// 初始化红外接收器
void IRReceiver::begin() {
    pinMode(pin_, INPUT_PULLUP);
    
    // 设置GPIO中断
    attachInterrupt(digitalPinToInterrupt(pin_), irInterrupt, CHANGE);
    
    initialized_ = true;
    lastTime = micros();
    
    DEBUG_PRINTLN("IR receiver initialized on pin " + String(pin_) + " using GPIO interrupt");
}

// 检查是否接收到红外信号
bool IRReceiver::hasSignal() {
    return initialized_ && irReceived;
}

// 获取接收到的红外代码
unsigned long IRReceiver::getCode() {
    if (!initialized_ || !irReceived) return 0;
    
    unsigned long code = irCode;
    irReceived = false;  // 清除标志
    
    return code;
}

// 执行与接收到的代码相关的操作
void IRReceiver::executeCommand(unsigned long code) {
    // 忽略重复信号和无效信号
    if (code == 0xFFFFFFFF || code == 0) {
        return;
    }

    DEBUG_PRINTLN("IR: Received code: 0x" + String(code, HEX));

    // 添加LED开关状态变量
    static bool ledPowerOn = true; // LED开关状态，默认开启
    static uint8_t lastBrightness = 50; // 记录关闭前的亮度

    switch (code) {
        case CH:
            DEBUG_PRINTLN("IR: LED 亮度开关");
            // 切换LED开关状态
            ledPowerOn = !ledPowerOn;
            if (ledPowerOn) {
                // 打开LED，恢复之前的亮度
                g_config.brightness = lastBrightness;
                setBrightness(map(g_config.brightness, 10, 100, 25, 255)); // 恢复亮度设置
                saveConfig();
                DEBUG_PRINTLN("LED已打开，亮度: " + String(g_config.brightness) + "%");
            } else {
                // 关闭LED，保存当前亮度并设置为0
                lastBrightness = g_config.brightness;
                setBrightness(0); // 直接设置亮度为0关闭LED
                DEBUG_PRINTLN("LED已关闭，保存亮度: " + String(lastBrightness) + "%");
            }
            break;

        case CH_DOWN:
            DEBUG_PRINTLN("IR: LED 亮度减小");
            // 只有在LED开启状态才能调节亮度 - 使用配置系统定义的范围和步进值
            if (ledPowerOn) {
                const ConfigRange &range = getConfigRange(CONFIG_BRIGHTNESS);
                if (g_config.brightness > range.min) {
                    int16_t newValue = g_config.brightness - range.step;
                    g_config.brightness = (newValue < range.min) ? range.min : newValue;
                    lastBrightness = g_config.brightness; // 更新记录的亮度
                    setBrightness(map(g_config.brightness, range.min, range.max, 25, 255)); // 实际应用亮度到硬件
                    saveConfig();
                    DEBUG_PRINTLN("亮度减小到: " + String(g_config.brightness) + "%");
                } else {
                    DEBUG_PRINTLN("亮度已达到最小值: " + String(range.min) + "%");
                }
            } else {
                DEBUG_PRINTLN("LED已关闭，请先打开LED");
            }
            break;

        case CH_UP:
            DEBUG_PRINTLN("IR: LED 亮度增加");
            // 只有在LED开启状态才能调节亮度 - 使用配置系统定义的范围和步进值
            if (ledPowerOn) {
                const ConfigRange &range = getConfigRange(CONFIG_BRIGHTNESS);
                if (g_config.brightness < range.max) {
                    int16_t newValue = g_config.brightness + range.step;
                    g_config.brightness = (newValue > range.max) ? range.max : newValue;
                    lastBrightness = g_config.brightness; // 更新记录的亮度
                    setBrightness(map(g_config.brightness, range.min, range.max, 25, 255)); // 实际应用亮度到硬件
                    saveConfig();
                    DEBUG_PRINTLN("亮度增加到: " + String(g_config.brightness) + "%");
                } else {
                    DEBUG_PRINTLN("亮度已达到最大值: " + String(range.max) + "%");
                }
            } else {
                DEBUG_PRINTLN("LED已关闭，请先打开LED");
            }
            break;

        case PLAY_UP:
            DEBUG_PRINTLN("IR: 七彩方向+");
            // 在频谱模式下调整七彩渐变方向+ - 使用配置系统定义的范围
            g_config.effectType = LED_MODE_SPECTRUM; // 确保为频谱模式
            g_config.colorScheme = COLOR_RAINBOW;    // 设置为七彩颜色方案
            g_config.rainbowType = 0;                // 设置为全彩模式
            
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_DIRECTION);
                if (g_config.rainbowDirection < range.max) {
                    g_config.rainbowDirection += range.step;
                } else {
                    g_config.rainbowDirection = range.min + range.step; // 循环回到最小值+步进（避免0触发自动模式）
                }
                currentRainbowDirection = g_config.rainbowDirection;
            }
            
            // setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("频谱模式七彩方向: " + String(g_config.rainbowDirection));
            break;

        case PLAY_DOWN:
            DEBUG_PRINTLN("IR: 七彩方向-");
            // 在频谱模式下调整七彩渐变方向- - 使用配置系统定义的范围
            g_config.effectType = LED_MODE_SPECTRUM; // 确保为频谱模式
            g_config.colorScheme = COLOR_RAINBOW;    // 设置为七彩颜色方案
            g_config.rainbowType = 0;                // 设置为全彩模式
            
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_DIRECTION);
                if (g_config.rainbowDirection > range.min + range.step) {
                    g_config.rainbowDirection -= range.step;
                } else {
                    g_config.rainbowDirection = range.max; // 循环到最大值
                }
                currentRainbowDirection = g_config.rainbowDirection;
            }
            
            // setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("频谱模式七彩方向: " + String(g_config.rainbowDirection));
            break;

        case PLAY_AUTO:
            DEBUG_PRINTLN("IR: 七彩自动模式");
            // 启用频谱模式的七彩自动渐变模式 - 使用配置系统定义的范围
            g_config.effectType = LED_MODE_SPECTRUM; // 确保为频谱模式
            g_config.colorScheme = COLOR_RAINBOW;    // 设置为七彩颜色方案
            g_config.rainbowType = 0;                // 设置为全彩模式
            
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_DIRECTION);
                g_config.rainbowDirection = range.min;  // 设置为最小值启动自动随机切换
                currentRainbowDirection = random(range.min + range.step, range.max + 1); // 随机生成方向
            }
            
            setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("频谱模式七彩自动渐变已启用，当前方向: " + String(currentRainbowDirection));
            break;

        case AUDIO_DOWN:
            DEBUG_PRINTLN("IR: 七彩速度减少");
            // 降低七彩速度 - 使用配置系统定义的范围和步进值
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_SPEED);
                if (g_config.rainbowSpeed > range.min) {
                    int16_t newValue = g_config.rainbowSpeed - range.step;
                    g_config.rainbowSpeed = (newValue < range.min) ? range.min : newValue;
                    saveConfig();
                    DEBUG_PRINTLN("七彩速度减少到: " + String(g_config.rainbowSpeed));
                } else {
                    DEBUG_PRINTLN("七彩速度已达到最小值: " + String(range.min));
                }
            }
            break;

        case AUDIO_UP:
            DEBUG_PRINTLN("IR: 七彩速度增加");
            // 增加七彩速度 - 使用配置系统定义的范围和步进值
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_SPEED);
                if (g_config.rainbowSpeed < range.max) {
                    int16_t newValue = g_config.rainbowSpeed + range.step;
                    g_config.rainbowSpeed = (newValue > range.max) ? range.max : newValue;
                    saveConfig();
                    DEBUG_PRINTLN("七彩速度增加到: " + String(g_config.rainbowSpeed));
                } else {
                    DEBUG_PRINTLN("七彩速度已达到最大值: " + String(range.max));
                }
            }
            break;

        case AUDIO_EQ:
            DEBUG_PRINTLN("IR: 自适应音量");
            // 切换音量自适应功能
            g_config.volumeAdaptive = !g_config.volumeAdaptive;
            saveConfig();
            if (g_config.volumeAdaptive) {
                DEBUG_PRINTLN("音量自适应已启用");
            } else {
                DEBUG_PRINTLN("音量自适应已禁用");
            }
            break;

        // 七彩模式控制 - 使用配置系统定义的范围
        case N1:
            DEBUG_PRINTLN("IR: 七彩模式1 - 全彩");
            g_config.effectType = LED_MODE_SPECTRUM;
            g_config.colorScheme = COLOR_RAINBOW;
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_TYPE);
                g_config.rainbowType = clampConfigValue(CONFIG_RAINBOW_TYPE, 0); // 全彩
            }
            setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("设置为频谱模式 + 七彩全彩类型");
            break;

        case N2:
            DEBUG_PRINTLN("IR: 七彩模式2 - 冷色");
            g_config.effectType = LED_MODE_SPECTRUM;
            g_config.colorScheme = COLOR_RAINBOW;
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_TYPE);
                g_config.rainbowType = clampConfigValue(CONFIG_RAINBOW_TYPE, 1); // 冷色
            }
            setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("设置为频谱模式 + 七彩冷色类型");
            break;

        case N3:
            DEBUG_PRINTLN("IR: 七彩模式3 - 暖色");
            g_config.effectType = LED_MODE_SPECTRUM;
            g_config.colorScheme = COLOR_RAINBOW;
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_TYPE);
                g_config.rainbowType = clampConfigValue(CONFIG_RAINBOW_TYPE, 2); // 暖色
            }
            setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("设置为频谱模式 + 七彩暖色类型");
            break;

        case N4:
            DEBUG_PRINTLN("IR: 七彩模式4 - 粉色");
            g_config.effectType = LED_MODE_SPECTRUM;
            g_config.colorScheme = COLOR_RAINBOW;
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_TYPE);
                g_config.rainbowType = clampConfigValue(CONFIG_RAINBOW_TYPE, 3); // 粉色
            }
            setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("设置为频谱模式 + 七彩粉色类型");
            break;

        case N5:
            DEBUG_PRINTLN("IR: 七彩模式5 - 青色");
            g_config.effectType = LED_MODE_SPECTRUM;
            g_config.colorScheme = COLOR_RAINBOW;
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_TYPE);
                g_config.rainbowType = clampConfigValue(CONFIG_RAINBOW_TYPE, 4); // 青色
            }
            setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("设置为频谱模式 + 七彩青色类型");
            break;

        case N6:
            DEBUG_PRINTLN("IR: 七彩模式6 - 紫色");
            g_config.effectType = LED_MODE_SPECTRUM;
            g_config.colorScheme = COLOR_RAINBOW;
            {
                const ConfigRange &range = getConfigRange(CONFIG_RAINBOW_TYPE);
                g_config.rainbowType = clampConfigValue(CONFIG_RAINBOW_TYPE, 5); // 紫色
            }
            setLEDEffect((EffectType)g_config.effectType);
            setColorScheme(g_config.colorScheme);
            saveConfig();
            DEBUG_PRINTLN("设置为频谱模式 + 七彩紫色类型");
            break;

        // 峰值点控制 - 使用配置系统定义的范围
        case N7:
            DEBUG_PRINTLN("IR: 峰值点0个");
            {
                const ConfigRange &range = getConfigRange(CONFIG_PEAK_DOT_COUNT);
                g_config.peakDotCount = clampConfigValue(CONFIG_PEAK_DOT_COUNT, 0); // 关闭峰值点
            }
            saveConfig();
            DEBUG_PRINTLN("峰值点已关闭");
            break;

        case N8:
            DEBUG_PRINTLN("IR: 峰值点1个");
            {
                const ConfigRange &range = getConfigRange(CONFIG_PEAK_DOT_COUNT);
                g_config.peakDotCount = clampConfigValue(CONFIG_PEAK_DOT_COUNT, 1); // 显示1个峰值点
            }
            saveConfig();
            DEBUG_PRINTLN("设置为显示1个峰值点");
            break;

        case N9:
            DEBUG_PRINTLN("IR: 峰值点2个");
            {
                const ConfigRange &range = getConfigRange(CONFIG_PEAK_DOT_COUNT);
                g_config.peakDotCount = clampConfigValue(CONFIG_PEAK_DOT_COUNT, 2); // 显示2个峰值点
            }
            saveConfig();
            DEBUG_PRINTLN("设置为显示2个峰值点");
            break;

        default:
            DEBUG_PRINTLN("IR: Unknown command: 0x" + String(code, HEX));
            break;
    }
}